package xq.gwt.ui.widgets.property;

import java.util.ArrayList;
import java.util.LinkedHashMap;

import xq.gwt.mvc.controller.TextArrayPropertyController;
import xq.gwt.mvc.model.ListItem;
import xq.gwt.mvc.model.StringArrayPropertyModel;
import xq.gwt.mvc.view.TextArrayPropertyView;

import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;

public class MultiSelectItemPropertyPresenter extends FormItemPropertyPresenter implements TextArrayPropertyView{
	
	protected SelectItem selectItem;	
	protected TextArrayPropertyController controller;	
	protected final String selectAll = "(All)";
	protected boolean isSelectAllSaved;
	protected LinkedHashMap<String, String> listItemMap = new LinkedHashMap<String, String>();
	private boolean blockChangedNotification;

    public MultiSelectItemPropertyPresenter(SelectItem selectItem){        
    	this.selectItem = selectItem;
    	formItem = this.selectItem;
        init();
        
    }
    
    public MultiSelectItemPropertyPresenter(){  	
    	
    	this.selectItem = new SelectItem();    	
    	formItem = selectItem;
    	init();
    }

	protected void init() {		
		selectItem.setMultiple(true);		
		selectItem.addChangedHandler(new ChangedHandler() {
			@Override
			public void onChanged(ChangedEvent event) {				
				if(blockChangedNotification)
					return;
				blockChangedNotification = true;
				
				selectAllSpecialBehaviour(selectItem.getValues());
				notifyViewChangedListeners();
				
				blockChangedNotification = false;
			}
		});		
				
		controller = new TextArrayPropertyController(this);
		super.controller = controller;
	}
    
	private void selectAllSpecialBehaviour(String[] values){
		
		
		if(values == null){
			isSelectAllSaved = false;
			return;
		}
		
		boolean isSelectAll = isSelectAll(values);		
		if(!isSelectAllSaved){
			if(isSelectAll){
				selectAll();
			}
		} else {
			if(isSelectAll){
				 //then something else is selected				
				selectItem.setValues(getValuesWithoutOptions());
				isSelectAll = false;
			} else {				
				selectNone();
			}
		}
		isSelectAllSaved = isSelectAll;
		
	}
	
	 
	
	private void selectAll(){		
		selectItem.setValues(getAllValues());
	}
	
	private void selectNone(){
		String[] vals = new String[]{};
		selectItem.setValues(vals);
	}
	
	private String[] getValuesWithoutOptions(){
		if(selectItem.getValues() == null){
			return null;
		}
		ArrayList<String> cleanValueList = new ArrayList<String>();
		for (int i = 0; i < selectItem.getValues().length; i++) {
			String val = selectItem.getValues()[i];
			if(!selectAll.equals(val)){
				cleanValueList.add(val);
			}			
		}
		String[] cleanValues = new String[cleanValueList.size()];
		cleanValueList.toArray(cleanValues);
		return cleanValues;
	}
	 
	
	private String[] getAllValues(){
		String[] values = new String[listItemMap.keySet().size()];
		listItemMap.keySet().toArray(values);
		return values;		
	}
	
    public void setModel(StringArrayPropertyModel model){    	
    	//selectItem
    	controller.setPropertyModel(model);
    	ListItem[] items = model.getValueItems(); 
    	if (items != null){    		
    		
    		listItemMap.put(selectAll, selectAll);
    		for (int i = 0; i < items.length; i++) {
				listItemMap.put(items[i].value, items[i].caption);
			}
    		selectItem.setValueMap(listItemMap);
    		selectItem.setSortField(1);
    	}
    	
    }
        
    public SelectItem getSelectItem() {
		return selectItem;
	}

	@Override
	public String[] getTextArray() {		
		String[] values = getValuesWithoutOptions(); 
		if(values != null){
			if(values.length == 0){
				return null;
			}
		}
				
		return values;
	}

	@Override
	public void setTextArray(String[] val) {
		selectItem.setValues(val);		
	}

	protected boolean isSelectAll(String[] values){
		if(values == null){
			return false;
		}
		for (int i = 0; i < values.length; i++) {
			if(values[i].equals(selectAll))
				return true;			
		}
		return false;
	}
		

}
